package com.logical.allhit.http;

import com.logical.allhit.gui.CaptchaImg;
import com.logical.allhit.gui.MainView;
import com.logical.allhit.setting.Setting;
import com.logical.allhit.setting.SettingChangeEvent;
import com.logical.allhit.setting.SettingChangeEventListener;
import com.logical.allhit.util.AddAttribute;
import com.logical.allhit.util.MsgLogger;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

/**
 * httppost.addHeader("Referer", referer);
 *
 * @author Sanjeet Jha
 */
public class HTTPClient implements SettingChangeEventListener {

    private static final HTTPClient instance = new HTTPClient();
    private DefaultHttpClient httpClient;
    private HttpEntity entity;
    private String imageCode;

    public String getImageCode() {
        return imageCode;
    }

    public void setImageCode(String imageCode) {
        this.imageCode = imageCode;
    }

    
    
    public static HTTPClient getInstance() {
        return instance;
    }

    private HTTPClient() {
        super();
        httpClient = new DefaultHttpClient();
        HttpParams params = new BasicHttpParams();
        params.setParameter(CoreProtocolPNames.USER_AGENT, Setting.getInstance().getUserAgent());
        params.setParameter(ClientPNames.DEFAULT_HOST, Setting.getInstance().getHost());
        httpClient.setParams(params);
        Setting.getInstance().addSettingChandeEventListener(this);
    }

    public HTTPClient getClient() {
        return instance;
    }

    @Override
    public void settingChenged(SettingChangeEvent evt) {
        httpClient = new DefaultHttpClient();
        HttpParams params = new BasicHttpParams();
        params.setParameter(CoreProtocolPNames.USER_AGENT, Setting.getInstance().getUserAgent());
        params.setParameter(ClientPNames.DEFAULT_HOST, Setting.getInstance().getHost());
        httpClient.setParams(params);
    }

    /**
     * to established session to server
     */
    public String[] setSession() {
        try {
            String msg = "Client trying connect to server...";
            MsgLogger.getInstance().showMsg(msg);
            HttpGet get = new HttpGet("http://"+Setting.getInstance().getHost()+"/login.php");
            HttpResponse response = httpClient.execute(get);

            String json = new String();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            String line = "";
            while ((line = reader.readLine()) != null) {
                json += line;
            }
            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }
            Document inboxDocument = Jsoup.parse(json);
            Element form = inboxDocument.getElementsByTag("form").first();
            Element imgs = form.getElementsByTag("img").first();
            msg = "session established successfully!";
            MsgLogger.getInstance().showMsg(msg);
            String[] parameter = {imgs.attr("src")};
            return parameter;
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, e.getMessage(), e);
            return null;
        }
    }

    /**
     * to login to server
     *
     * @param userName user name
     * @param password password of account
     * @param usertype user type
     * @return true of login successfully or
     */
    public boolean login(String userName, String password, String usertype) {
        try {
            String msg = "Client trying login to server and User Name: " + userName;
            MsgLogger.getInstance().showMsg(msg);
            String[] params = setSession();
            if (params != null) {
                new CaptchaImg(MainView.getInstance().getFram(), true, params[0], CaptchaImg.login_image_code).setVisible(true);
            }
            HttpPost httpPost = new HttpPost("http://"+Setting.getInstance().getHost()+"/index.php");
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("emailId", userName));
            nvps.add(new BasicNameValuePair("passwords", password));
            nvps.add(new BasicNameValuePair("user_type", (usertype.equals("pro_user") ? "1" : "0")));
            nvps.add(new BasicNameValuePair("submit", ""));
            nvps.add(new BasicNameValuePair("6_letters_code", imageCode));

            httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            if (!Setting.getInstance().getProxys().isEmpty()) {
                httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, ProxyManger.getInstance().getNextProxy());
            }
            
            HttpResponse response = httpClient.execute(httpPost);

            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }

            msg = "Login successfully!";
            MsgLogger.getInstance().showMsg(msg);
            return checkLogin();
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, userName + " failed to login... ", e);
            return false;
        }
    }

    public String loadmail(AddAttribute attribute) throws Exception {
        try {
            String mail = new String();
            HttpPost httpPost = new HttpPost(attribute.getAction());
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair(attribute.getPostName(), attribute.getPostValue()));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            HttpResponse response = httpClient.execute(httpPost);

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            String line = "";
            while ((line = reader.readLine()) != null) {
                mail += line;
            }

            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }
            return mail;
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, " failed to open mail... ", e);
            throw e;
        }
    }

    public boolean logout(String type) {
        try {
            HttpGet get = new HttpGet("http://"+Setting.getInstance().getHost()+"/" + type + "/logout.php");
            HttpResponse response = httpClient.execute(get);
            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }
            String msg = "successful logout. ";
            MsgLogger.getInstance().showMsg(msg);
            return true;
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, e.getMessage(), e);
            return false;
        }
    }

    private boolean checkLogin() {
        String msg = GET("http://"+Setting.getInstance().getHost()+"/pro_user/admin.php");
        return !msg.equals("<script>document.location.href="+"http://"+Setting.getInstance().getHost()+"'/index.php'</script>Please Enable JavaScript in your Browser.");
    }

    public String GET(String url) {
        try {
            HttpGet get = new HttpGet(url);
            HttpResponse response = httpClient.execute(get);

            String json = new String();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            String line = "";
            while ((line = reader.readLine()) != null) {
                json += line;
            }
            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }
            return json;
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, e.getMessage(), e);
            return "";
        }
    }

    public byte[] GETIMAGE(String url) {
        try {
            HttpGet get = new HttpGet(url);
            HttpResponse response = httpClient.execute(get);

            //byte[] json = new byte[Integer.parseInt(response.getHeaders("Content-Length")[0].getValue())];
            byte[] json = new byte[1024 * 1024 * 3];
            DataInputStream dataIs = new DataInputStream(response.getEntity().getContent());
            //dataIs.readFully(json);

            byte[] line = new byte[50];
            int i = 0;
            while (true) {
                try {
                    dataIs.readFully(line);
                    System.arraycopy(line, 0, json, i* 50, 50);
                    i++;
                } catch (Exception ex) {
                    break;
                }
            }
            
            byte[] output = new byte[i * 50];
            
            System.arraycopy(json, 0, output, 0, i * 50);
            
            entity = response.getEntity();
            if (entity != null) {
                entity.consumeContent();
            }
            return output;
            
        } catch (Exception e) {
            Logger.getLogger(HTTPClient.class.getName()).log(Level.WARNING, e.getMessage(), e);
            return null;
        }
    }

    public void shutdown() {
        httpClient.getConnectionManager().shutdown();
    }
}
